/**
 * 
 */
package scriptrunner.execution;

import java.io.Serializable;

/**
 * @author Administrator
 * 
 */
public class EvalTimesExpr extends EvaluateExpr implements Serializable {

	/**
	 * 
	 */
	private static final long serialVersionUID = 5200292112200438628L;

	public EvalTimesExpr(EvaluateExpr eeLeft, EvaluateExpr eeRight) {
		this.eeLeft = eeLeft;
		this.eeRight = eeRight;
	}

	@Override
	public ValueObject CalculateResult(Session se) throws ExecuteErrorException {
		ValueObject left = eeLeft.CalculateResult(se);
		ValueObject right = eeRight.CalculateResult(se);

		if (left instanceof ArithmeticCalculable
				&& right instanceof ArithmeticCalculable) {
			ArithmeticCalculable aLeft = (ArithmeticCalculable) left;
			ArithmeticCalculable aRight = (ArithmeticCalculable) right;

			if (aLeft.getClass() == aRight.getClass())
				return aLeft.Times(aRight);
			else if (aLeft.ArithmeticTypePreference() < aRight
					.ArithmeticTypePreference()) {
				try {
					ArithmeticCalculable nLeft = (ArithmeticCalculable) aRight
							.getClass().newInstance();
					nLeft.ParseFromString(aLeft.SaveValueToString());
					return nLeft.Times(aRight);
				} catch (Throwable o) {
					throw new ExecuteErrorException("Times operation failed");
				}
			} else // (aLeft.ArithmeticTypePreference() >
			// aRight.ArithmeticTypePreference())
			{
				try {
					ArithmeticCalculable nRight = (ArithmeticCalculable) aLeft
							.getClass().newInstance();
					nRight.ParseFromString(aRight.SaveValueToString());
					return aLeft.Times(nRight);
				} catch (Throwable o) {
					throw new ExecuteErrorException("Times operation failed");
				}
			}
		} else
			throw new ExecuteErrorException("Times operation failed");
	}

	EvaluateExpr eeLeft, eeRight;
}
